/**
 * 
 */
package engine.operators;

import java.util.logging.Level;
import java.util.logging.Logger;

import engine.ObjectiveFunction;
import engine.Operator;
import engine.Population;
import engine.operators.util.StatisticUtils;

public class ReportStatisticsOperator<T> implements
		Operator<T> {
	
	private static final Logger LOGGER = Logger.getLogger(ReportStatisticsOperator.class.getName());
	
	

	private ObjectiveFunction<T> objFunction;

	private StatisticUtils<T> statUtil;

	public ReportStatisticsOperator(
			ObjectiveFunction<T> objectiveFunction) {
		this.objFunction = objectiveFunction;
		this.statUtil = new StatisticUtils<T>(objFunction);
	}

	@Override
	public Population<T> apply(
			Population<T> population) {

		T max = statUtil.max(population.getIndividuals());
		T min = statUtil.min(population.getIndividuals());
		
		double mean = statUtil.mean(population.getIndividuals());
		double stdDev = statUtil.stdDev(population.getIndividuals(), mean);


		if (LOGGER.isLoggable(Level.INFO)) {
			for (T ind : population.getIndividuals()) {
				LOGGER.info(String.format("%04.3f", objFunction.compute(ind)) + ": "
						+ ind);
			}
		}
		LOGGER.warning("Best individual: "
				+ objFunction.compute(max) + ": " + max);
		LOGGER.warning("Worst individual: "
				+ objFunction.compute(min) + ": " + min);
		LOGGER.warning("Mean of individuals: " + mean);
		LOGGER.warning("Standard deviation of individuals: " + stdDev);
		
		return population;
	}
}